from enum import StrEnum
import logging
import time
from typing import Tuple
import requests
from configs import app_config
from libs.hmac_header import get_hmac_header
from services.errors.robots import InvalidRobotAgentTagError, RobotActiveNotifyError
class TaskState(StrEnum):
    DEALLING = "DEALLING"
    FAILED = "FAILED"
    SUCCESS = "SUCCESS"
    SEARCH_TIMEOUT= "SEARCH_TIMEOUT"

class RobotRemoteService:
    """
    机器人WS后台状态查询服务
    """
    

    ACTIVE_READY_ENDPOINT = "/robots/active/{robot_id}/ready"
    @classmethod
    def is_ready_to_active(cls,robot_id: str) -> Tuple[bool,str, str,str,str]:
        base_url = app_config.REMOTE_ROBOT_SERVER_HOST.rstrip('/')
        endpoint = cls.ACTIVE_READY_ENDPOINT.format(robot_id=robot_id)
        
        url = f"{base_url}/{endpoint.lstrip('/')}"
        
        try:
            response = requests.get(url,headers=get_hmac_header(), timeout=2)  # 设置5秒超时
            response.raise_for_status()  # 如果状态码不是2xx，抛出异常
            
            data = response.json()
            is_ready = data.get("is_ready", False)
            data_dict = data.get("data", {})
            ip_addr = data_dict.get("ip_addr", "")
            bluetooth_id = data_dict.get("bluetooth_id", "")
            hardware_version = data_dict.get("hardware_version", "")
            fireware_version = data_dict.get("fireware_version", "")
            
            return is_ready, ip_addr,bluetooth_id,hardware_version,fireware_version
        
        except requests.exceptions.RequestException as e:
            logging.error(f"Is_Ready_For_Active:Request failed for agent {robot_id}: {e}", exc_info=False)
            return False,"", "","",""
        
    IS_ONLINE_ENDPOINT = "/robots/active/{robot_id}/is_alive"
    @classmethod
    def is_online(cls,robot_id: str)->Tuple[bool,dict|None]:
        base_url = app_config.REMOTE_ROBOT_SERVER_HOST.rstrip('/')
        endpoint = cls.IS_ONLINE_ENDPOINT.format(robot_id=robot_id)
        
        url = f"{base_url}/{endpoint.lstrip('/')}"
        
        try:
            response = requests.get(url,headers=get_hmac_header(), timeout=2)  # 设置5秒超时
            response.raise_for_status()  # 如果状态码不是2xx，抛出异常
            
            data = response.json()
            is_online = data.get('is_alive',False)
            if not is_online:
                return is_online,{}
            return is_online,data.get('data',{})
        
        except requests.exceptions.RequestException as e:
            logging.error(f"Is_Online:Request failed for agent {robot_id}: {e}", exc_info=False)
            return False, {}
        
    ACTIVE_DONE_ENDPOINT='/robots/active/{robot_id}/done'
    @classmethod
    def active_notify(cls,robot_id: str,config:dict)->tuple[bool,str]:
        base_url = app_config.REMOTE_ROBOT_SERVER_HOST.rstrip('/')
        endpoint = cls.ACTIVE_DONE_ENDPOINT.format(robot_id=robot_id)
        
        url = f"{base_url}/{endpoint.lstrip('/')}"
        
        try:
            data= {
                "ver":"1.0",
                "type":"activated",
                "timestamp":int(time.time()),
                "data":{
                    "device_id":robot_id,
                    "data":config
                }
            }
            response = requests.post(url,json=data,headers=get_hmac_header(), timeout=2)  # 设置5秒超时
            response.raise_for_status()  # 如果状态码不是2xx，抛出异常
            
            data = response.json()
            if data and data.get('status')==True:
                return True,data.get("task_id")
            return False,data.get("message")
        
        except requests.exceptions.RequestException as e:
            logging.error(f"Is_Online:Request failed for agent {robot_id}: {e}", exc_info=False)
            raise RobotActiveNotifyError()
        except Exception as e:
            logging.error(f"Is_Online:Request failed for agent {robot_id}: {e}", exc_info=False)
            raise RobotActiveNotifyError()

    REVERS_CONTROL_ENDPOINT='/robots/reverse/{robot_id}/config'    
    @classmethod
    def remote_config(cls,robot_id:str,config_param:dict)->tuple[bool,str]:
        base_url = app_config.REMOTE_ROBOT_SERVER_HOST.rstrip('/')
        endpoint = cls.REVERS_CONTROL_ENDPOINT.format(robot_id=robot_id)
        url = f"{base_url}/{endpoint.lstrip('/')}"
        
        try:
            data= {
                "ver":"1.0",
                "type":"config",
                "timestamp":int(time.perf_counter()),
                "data":{
                    "device_id":robot_id,
                    "data":config_param
                }
            }
            response = requests.post(url,json=data,headers=get_hmac_header(), timeout=2)  # 设置5秒超时
            response.raise_for_status()  # 如果状态码不是2xx，抛出异常
            
            data = response.json()
            logging.info(f"Response from agent {robot_id}: {data}")
            if data and data.get('status'):
                return True,data.get("task_id")
            return False,data.get("message")
        
        except requests.exceptions.RequestException as e:
            logging.error(f"Is_Online:Request failed for agent {robot_id}: {e}", exc_info=False)
            raise RobotActiveNotifyError()
        except Exception as e:
            logging.error(f"Is_Online:Request failed for agent {robot_id}: {e}", exc_info=False)
            raise RobotActiveNotifyError()
        
    TASK_STATE_ENDPOINT='/robots/task/{task_id}/state'    
    @classmethod
    def task_state(cls,task_id:str)->tuple[bool,TaskState,str]:
        base_url = app_config.REMOTE_ROBOT_SERVER_HOST.rstrip('/')
        endpoint = cls.TASK_STATE_ENDPOINT.format(task_id=task_id)
        url = f"{base_url}/{endpoint.lstrip('/')}"
        
        try:
            
            response = requests.get(url,headers=get_hmac_header(), timeout=2)  # 设置5秒超时
            response.raise_for_status()  # 如果状态码不是2xx，抛出异常
            
            data = response.json()
            if data:
                status = data.get('status')
                if status =='fail':
                    return False,TaskState.FAILED,data.get("msg","")
                elif status == 'success':
                    return True,TaskState.SUCCESS,data.get("msg","")
                elif status == 'pending':
                    return False,TaskState.DEALLING,data.get("msg","")
            return False,TaskState.SEARCH_TIMEOUT,""
        except requests.exceptions.RequestException as e:
            logging.error(f"task_state:Request failed for TASK {task_id}: {e}", exc_info=False)
            raise RobotActiveNotifyError()
        except Exception as e:
            logging.error(f"task_state:Request failed for TASK {task_id}: {e}", exc_info=True)
            raise RobotActiveNotifyError()
        

    ROBOT_AGENT_ENDPOINT = "/robots/agents/{agent_tag}"
    @classmethod
    def get_robot_agents(cls,agent_tag: str)->dict:
        if agent_tag not in ["RobotAgent","EmojiPredictAgent","TimbrePredictAgent"]:
            raise InvalidRobotAgentTagError()
        base_url = app_config.REMOTE_ROBOT_SERVER_HOST.rstrip('/')
        endpoint = cls.ROBOT_AGENT_ENDPOINT.format(agent_tag=agent_tag)
        
        url = f"{base_url}/{endpoint.lstrip('/')}"
        
        try:
            response = requests.get(url,headers=get_hmac_header(), timeout=5)  # 设置5秒超时
            response.raise_for_status()  # 如果状态码不是2xx，抛出异常
            
            data = response.json()
            return data
        
        except requests.exceptions.RequestException as e:
            logging.error(f"get_robot_agents:Request failed for agent {agent_tag}: {e}", exc_info=True)
            return {}
        
 